import sys
import os
import random
import argparse
import jsonlib
import time
import sqlite3

columns=[("date","date"), 
            ("service_name","node"), 
            ("osusername","node"), 
            ("program","node"), 
            ("hostname","node"), 
            ("clientip","node"), 
            ("count","counter")]

def genrandomdata(step):
    service_names=('orcl', 'xe', 'ora.test', 'fsi', 'sap')
    usernamecount=15000
    programcount=400
    hostcount=1400
    ipranges=('172.16.1.', '172.16.2.', '172.16.3.', '172.16.4.')
        
    random.seed()
    service_name=service_names[random.randint(0, 4)]
    random.seed()
    osusername='user{0}'.format(random.randint(0, usernamecount))
    random.seed()
    program='program{0}'.format(random.randint(0, programcount))
    random.seed()
    hostname='host{0}'.format(random.randint(0, hostcount))
    random.seed()
    whichrange=random.randint(0, len(ipranges)-1)
    random.seed()
    clientip='{0}{1}'.format(ipranges[whichrange], random.randint(1,254))
    random.seed()
    date=""
    if(step=='y'):
        date="%d" % (random.randint(2008, 2010))
    elif(step=='m'):
        date="%d%02d" % (random.randint(2008, 2010), random.randint(1, 12))
    elif(step=='d'):
        date="%d%02d%02d" % (random.randint(2008, 2010), random.randint(1, 12), random.randint(1, 31))
    elif(step=='h'):
        date="%d%02d%02d%02d" % (random.randint(2008, 2010), random.randint(1, 12), random.randint(1, 31), random.randint(0, 23))

    return(date, service_name,  osusername,  program,  hostname,  clientip)

def getvariables(fields,  step):
    start=fields[1].find('PROGRAM')+8
    end=fields[1].find(')', start)
    program=fields[1][start:end]
    start=fields[1].find('USER')+5
    end=fields[1].find(')', start)
    osusername=fields[1][start:end]
    start=fields[1].find('SERVICE_NAME')+13
    if(start==0):
        start=fields[1].find('SID')+4
    end=fields[1].find(')', start)
    service_name=fields[1][start:end]
    start=fields[1].find('HOST')+5
    end=fields[1].find(')', start)
    hostname=fields[1][start:end]
    start=fields[2].find('HOST')+5
    end=fields[2].find(')', start)
    clientip=fields[2][start:end]
    format="%d-%b-%Y %H:%M:%S"
    time_str=time.strptime(fields[0][:-1],  format)
    if(step=='y'):
       date="%d" % (time_str.tm_year)
    elif(step=='m'):
        date="%d%d" % (time_str.tm_year, time_str.tm_mon)
    elif(step=='d'):
        date="%d%d%d" % (time_str.tm_year, time_str.tm_mon, time_str.tm_day)
    elif(step=='h'):
        date="%d%d%d%d" % (time_str.tm_year, time_str.tm_mon, time_str.tm_day, time_str.tm_hour)
    
    return(date, service_name,  osusername,  program,  hostname,  clientip)

def initdb(db,  source,  columns):
    con = sqlite3.connect(args.db)
    c = con.cursor()
    c.execute("create table if not exists listener(sourceid integer, date vahrchar(10), service_name varchar(255),\
                    osusername varchar(255), program varchar(1500), hostname varchar(500), clientip varchar(30), count int);")
    c.execute("create table if not exists config( column vahrchar(255), type varchar(255), table_name varchar(255));")
    c.execute("create table if not exists sources(id INTEGER PRIMARY KEY AUTOINCREMENT, service_name varchar(1500));")
    c.execute("insert into sources values(NULL,?);", (source, ))
    c.execute("select max(id) from sources;")
    sourceid=c.fetchone()[0]
    c.execute("delete from config where table_name='listener';")
    for i in columns:
        c.execute("insert into config values(?,?,'listener');", i)
    return (con, c,  sourceid)

parser=argparse.ArgumentParser(
            description = 'Parse a 11g listern file to sqlite or generate random data',
            epilog = 'Tested on windows')
parser.add_argument('-f','--file',  help = 'Listsern file')
parser.add_argument('-c','--count',  type=int,  help = 'Number of randomly generated listener lines')
parser.add_argument('-d','--datetype',  help = 'Date aggregate for randomly generated listener lines')
parser.add_argument('-g','--db',  help = 'Database file')

args=parser.parse_args()

osusers_dict={}
service_names_dict={}
programs_dict={}
hosts_dict={}
clientips_dict={}
sourceid=0

listener_line_dict_bydate={}

if(args.db):
    if(args.count):
        (con, c,  sourceid) = initdb(args.db, "random",  columns)
    else:
        (con, c,  sourceid)= initdb(args.db, os.path.abspath(args.file),  columns)

if(args.count):
    for i in range(args.count):
        (date,  service_name,  osusername,  program,  hostname,  clientip)=genrandomdata(args.datetype)
        key=str.join("|", (date, service_name,  osusername,  program,  hostname,  clientip))
        if(key not in listener_line_dict_bydate):
            listener_line_dict_bydate[key]=1
        else:
            listener_line_dict_bydate[key]=listener_line_dict_bydate[key]+1
else:
    f=open(args.file, 'r')
    for line in f:
        if(line.startswith(' <txt>')):
            fields=line[6:].split('*')
            if(len(fields)==6):
                (date, service_name,  osusername,  program,  hostname,  clientip)=getvariables(fields, 'm')
                key=str.join("|", (date, service_name,  osusername,  program,  hostname,  clientip))
                if(key not in listener_line_dict_bydate):
                    listener_line_dict_bydate[key]=1
                else:
                    listener_line_dict_bydate[key]=listener_line_dict_bydate[key]+1


for i in (listener_line_dict_bydate):
    print("%s|%s" % (i, listener_line_dict_bydate[i]))
    (date, service_name,  osusername,  program,  hostname,  clientip)=str.split(i,"|")
    if(args.db):
        c.execute("insert into listener values(?,?,?,?,?,?,?,?)", (sourceid, date, service_name,  osusername,  program,  hostname,  clientip, listener_line_dict_bydate[i]))
    
if(args.db):
    con.commit()
    c.close()
